home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 3 / Cream of the Crop 3.iso / comm / wnos5src.zip / KSUBR.C < prev    next >
Text File  |  1993-11-17  |  6KB  |  255 lines

  1. /* Machine or compiler-dependent portions of kernel
  2.  * Turbo-C version for PC
  3.  *
  4.  * Copyright 1991 Phil Karn, KA9Q
  5.  */
  6. #include <stdio.h>
  7. #include <dos.h>
  8. #include "global.h"
  9. #include "proc.h"
  10. #include "pc.h"
  11. #include "commands.h"
  12.  
  13. static int near chkintstk __ARGS((void));
  14.  
  15. #undef PROCLOG
  16.  
  17. #ifdef PROCLOG
  18. int stkutil __ARGS((struct proc *pp));
  19. #else
  20. static int near stkutil __ARGS((struct proc *pp));
  21. #endif
  22.  
  23. /* Template for contents of jmp_buf in Turbo C */
  24. struct env {
  25.     unsigned    sp;
  26.     unsigned    ss;
  27.     unsigned    flag;
  28.     unsigned    cs;
  29.     unsigned    ip;
  30.     unsigned    bp;
  31.     unsigned    di;
  32.     unsigned    es;
  33.     unsigned    si;
  34.     unsigned    ds;
  35. };
  36.  
  37. void
  38. kinit(void)
  39. {
  40.     int i;
  41.  
  42.     /* Initialize interrupt stack for high-water-mark checking */
  43.     for(i = 0; i < 512; i++)
  44.         Intstk[i] = STACKPAT;
  45. }
  46.  
  47. /* Print process table info
  48.  * Since things can change while ps is running, the ready proceses are
  49.  * displayed last. This is because an interrupt can make a process ready,
  50.  * but a ready process won't spontaneously become unready. Therefore a
  51.  * process that changes during ps may show up twice, but this is better
  52.  * than not having it showing up at all.
  53.  */
  54. int
  55. ps(int argc,char **argv,void *p)
  56. {
  57.     struct proc *pp;
  58.     struct env *ep;
  59.  
  60.     char *Taskers[] = {
  61.         "",
  62.         "DoubleDos",
  63.         "DesqView",
  64.         "Windows3",
  65.         "OS/2",
  66.     };
  67.  
  68.     tprintf("Stack %x max intstk %u",getss(),chkintstk());
  69.  
  70.     if(Mtasker != 0)
  71.         tprintf(" Running under %s",Taskers[Mtasker]);
  72.  
  73.     tputs("\nPID  SP   size  max   event  fl  in  out name\n");
  74.  
  75.     for(pp = Susptab; pp != NULLPROC; pp = pp->next) {
  76.         ep = (struct env *)&pp->env;
  77.         tprintf("%-5lx%-5lx%-6u%-6u%-7lx%c%c%c %d %d %s\n",
  78.          ptol(pp),
  79.          ptol((void *)MK_FP(ep->ss,ep->sp)),
  80.          pp->stksize,
  81.          stkutil(pp),
  82.          ptol(pp->event),
  83.          pp->i_state ? 'I' : ' ',
  84.          (pp->state & WAITING) ? 'W' : ' ',
  85.          (pp->state & SUSPEND) ? 'S' : ' ',
  86.          pp->input, pp->output,
  87.          pp->name);
  88.     }
  89.     for(pp = Waittab; pp != NULLPROC; pp = pp->next) {
  90.         ep = (struct env *)&pp->env;
  91.         tprintf("%-5lx%-5lx%-6u%-6u%-7lx%c%c%c %d %d %s\n",
  92.          ptol(pp),
  93.          ptol((void *)MK_FP(ep->ss,ep->sp)),
  94.          pp->stksize,
  95.          stkutil(pp),
  96.          ptol(pp->event),
  97.          pp->i_state ? 'I' : ' ',
  98.          (pp->state & WAITING) ? 'W' : ' ',
  99.          (pp->state & SUSPEND) ? 'S' : ' ',
  100.          pp->input,
  101.          pp->output,
  102.          pp->name);
  103.     }
  104.     for(pp = Rdytab; pp != NULLPROC; pp = pp->next) {
  105.         ep = (struct env *)&pp->env;
  106.         tprintf("%-5lx%-5lx%-6u%-6u       %c%c%c %d %d %s\n",
  107.          ptol(pp),
  108.          ptol((void *)MK_FP(ep->ss,ep->sp)),
  109.          pp->stksize,
  110.          stkutil(pp),
  111.          pp->i_state ? 'I' : ' ',
  112.          (pp->state & WAITING) ? 'W' : ' ',
  113.          (pp->state & SUSPEND) ? 'S' : ' ',
  114.          pp->input,
  115.          pp->output,
  116.          pp->name);
  117.     }
  118.     if(Curproc != NULLPROC) {
  119.         ep = (struct env *)&Curproc->env;
  120.         tprintf("%-5lx%-5lx%-6u%-6u       %c   %d %d %s\n",
  121.          ptol(Curproc),
  122.          ptol((void *)MK_FP(ep->ss,ep->sp)),
  123.          Curproc->stksize,
  124.          stkutil(Curproc),
  125.          Curproc->i_state ? 'I' : ' ',
  126.          Curproc->input,
  127.          Curproc->output,
  128.          Curproc->name);
  129.     }
  130.     return 0;
  131. }
  132.  
  133. #ifdef PROCLOG
  134. int
  135. #else
  136. static int near
  137. #endif
  138. stkutil(struct proc *pp)
  139. {
  140.     int16 *sp = pp->stack;
  141.     unsigned int i = pp->stksize;
  142.  
  143.     for( ; *sp == STACKPAT && sp < (pp->stack + pp->stksize); sp++) {
  144.         i--;
  145.     }
  146.     return (int)i;
  147. }
  148.  
  149. /* Return number of used words in interrupt stack. Note hardwired value
  150.  * for stack size; this is also found in the various .asm files
  151.  */
  152. static int near
  153. chkintstk(void)
  154. {
  155.     int i = 512;
  156.     int16 *cp = Intstk;
  157.  
  158.     for( ; i != 0 && *cp == STACKPAT; cp++) {
  159.         i--;
  160.     }
  161.     return i;
  162. }
  163.  
  164. #ifdef MDEBUG
  165. /* Verify that stack pointer for current process is within legal limits;
  166.  * also check that no one has dereferenced a null pointer
  167.  */
  168. void
  169. chkstk(void)
  170. {
  171.     struct proc *Curproct = Curproc;
  172.  
  173.     int16 *sbase, *stop, *sp = (int16 *)(MK_FP(_SS,_SP));
  174.  
  175.     if(_SS == _DS) {
  176.         /* Probably in interrupt context */
  177.         return;
  178.     }
  179.     if((sbase = Curproct->stack) == NULL) {
  180.         /* Main task -- too hard to check */
  181.         return;
  182.     }
  183.     stop = sbase + Curproct->stksize;
  184.  
  185.     if(sp < sbase || sp >= stop) {
  186.         dirps();
  187.         iostop();
  188.         printf("\nStack violation, process %s\n",Curproct->name);
  189. #ifdef MDEBUG
  190.         printf("SP=%lx, legal stack range [%lx,%lx] ",
  191.             ptol(sp),ptol(sbase),ptol(stop));
  192. #endif
  193.         printf("stksize=%u, maxstk=%u\n\n",Curproct->stksize,stkutil(Curproct));
  194.         exit(254);
  195.     }
  196. }
  197. #endif
  198.  
  199. /* Machine-dependent initialization of a task */
  200. void
  201. psetup(
  202. struct proc *pp,    /* Pointer to task structure */
  203. int iarg,            /* Generic integer arg */
  204. void *parg1,        /* Generic pointer arg #1 */
  205. void *parg2,        /* Generic pointer arg #2 */
  206. void (*pc)())        /* Initial execution address */
  207. {
  208.     struct env *ep;
  209.  
  210.     /* Set up stack to make it appear as if the user's function was called
  211.      * by killself() with the specified arguments. When the user returns,
  212.      * killself() automatically cleans up.
  213.      *
  214.      * First, push args on stack in reverse order, simulating what C
  215.      * does just before it calls a function.
  216.      */
  217.     unsigned *stktop = ((unsigned *)pp->stack + pp->stksize);
  218.  
  219. #ifdef    LARGEDATA
  220.     *--stktop = FP_SEG(parg2);
  221. #endif
  222.     *--stktop = FP_OFF(parg2);
  223. #ifdef    LARGEDATA
  224.     *--stktop = FP_SEG(parg1);
  225. #endif
  226.     *--stktop = FP_OFF(parg1);
  227.     *--stktop = iarg;
  228.  
  229.     /* Now push the entry address of killself(), simulating the call to
  230.      * the user function.
  231.      */
  232. #ifdef    LARGECODE
  233.     *--stktop = FP_SEG(killself);
  234. #endif
  235.     *--stktop = FP_OFF(killself);
  236.  
  237.     /* Set up task environment. Note that for Turbo-C, the setjmp
  238.      * sets the interrupt enable flag in the environment so that
  239.      * interrupts will be enabled when the task runs for the first time.
  240.      * Note that this requires newproc() to be called with interrupts
  241.      * enabled!
  242.      */
  243.     setjmp(pp->env);
  244.  
  245.     ep = (struct env *)&pp->env;
  246.     ep->ss = FP_SEG(stktop);
  247.     ep->sp = FP_OFF(stktop);
  248.     ep->cs = FP_SEG(pc);    /* Doesn't hurt in small model */
  249.     ep->ip = FP_OFF(pc);
  250.  
  251.     /* Task initially runs with interrupts on */
  252.     pp->i_state = 1;
  253. }
  254.  
  255.